﻿using BenCaoXuan.Infrastructure.Attr;
using BenCaoXuan.Infrastructure.Dto;
using BenCaoXuan.Infrastructure.Dto.Admin.product;
using BenCaoXuan.Infrastructure.Dto.Admin.System;
using BenCaoXuan.Infrastructure.EFCore.MySql;
using BenCaoXuan.Infrastructure.IOC;
using BenCaoXuan.Infrastructure.Tools;
using BenCaoXuan.Service.Interface.admin;
using Google.Protobuf.WellKnownTypes;
using Microsoft.EntityFrameworkCore;
using ServiceStack;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BenCaoXuan.Service.Instance.admin
{
    [Inject_]
    public class Product_Service : Base_Service, I_Product_Service
    {
        private readonly Product_IOC _product_IOC;
        private readonly Sys_IOC _sys_IOC;
        private readonly Customer_IOC _customer_IOC;

        public Product_Service(Product_IOC product_IOC, 
            
            Customer_IOC customer_IOC,
            Sys_IOC sys_IOC)
        {
            _product_IOC = product_IOC;
            _sys_IOC = sys_IOC;
            _customer_IOC = customer_IOC;
        }

        /// <summary>
        /// 新增产品
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Add_Product(AddProduct_Dto dto)
        {
            //新增
            Product data = new Product()
            {
                PId = Config.GUID(),
                PProductAttention = dto.attention,
                PCover = dto.cover,
                PDescription = dto.description,
                PIsBan = 0,
                PIsGroup = 0,
                PName = dto.name,
                PPhoto = dto.photo.Join(","),
                PProductEffect = dto.effect,
                PRemark = dto.remark,
                PTypeId = dto.typeId,
                PCreateTime = DateTime.Now,
                PUpdateTime = DateTime.Now
            };
            _product_IOC._product_EFCore.Add(data);
            _product_IOC._product_EFCore.SaveChanges();
            List<ProductSpec> list = new List<ProductSpec>();
            dto.specs!.ForEach(d =>
            {
                list.Add(new ProductSpec()
                {
                    PsId = Config.GUID2(),
                    PsName = d.name,
                    PsIsBan = 0,
                    PsPrice = d.price,
                    PsProductId = data.PId,
                    PsCreateTime = DateTime.Now,


                });
            });
            _product_IOC._productSpecs_EFCore.AddRange(list);
            await _product_IOC._productSpecs_EFCore.SaveChangesAsync();
           
            //新增产品的佣金规则
            CommissionRule commissionRule=new CommissionRule() { 
            CrCommissionRate=(decimal)dto.commissionRate!,
            CrCount=0,
            CrCreateTime= DateTime.Now,
            CrDescription=dto.commissionDesc,
            CrId=Config.GUID(),
            CrPackageId=null,
            CrProductId=data.PId,
            CrProductName=data.PName,
            CrProductType=0
            };
            _customer_IOC._commissionRules_EFCore.Add(commissionRule);

            var result = await _customer_IOC._commissionRules_EFCore.SaveChangesAsync();

            return Get_Result(result);
        }

        /// <summary>
        /// 新增产品文章
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Add_ProductArticle(AddProductArticle_Dto dto)
        {
            //先判断该产品是否存在文章,存在删除不存在添加
            var isdel =await _product_IOC._productArticle_EFCore.GetAll(d => d.PaProductId == dto.productId).SingleOrDefaultAsync();
            if (isdel != null)
            {
                _product_IOC._productArticle_EFCore.Delete(isdel);
                await _product_IOC._productArticle_EFCore.SaveChangesAsync();
            }

            var product = _product_IOC._product_EFCore.GetAll().ToList();
            var productName = product.Where(d=>d.PId==dto.productId).Select(d=>d.PName).Single();
            var typeid = product.Where(d => d.PId == dto.productId).Select(d => d.PTypeId).Single();
            var typeName =await _sys_IOC._sysDictionary_EFCore.GetAll(d => d.DId == typeid).Select(d => d.DName).SingleAsync();
            ProductArticle productArticle = new ProductArticle() {
                PaId = Config.GUID2(),
                PaContent = dto.articleContent,
                PaCreateTime = DateTime.Now,   
                PaLookCount = 0,
                PaPublishTime=null,
                PaCover=dto.articleCover,
                PaProductId=dto.productId,
                PaTitle=dto.articleTitle,
                PaStatus = 0,
                PaProductName=productName!,
                PaProductType=typeName!

            };

            _product_IOC._productArticle_EFCore.Add(productArticle);
            var result = await _product_IOC._productArticle_EFCore.SaveChangesAsync();
            return Get_Result(result);

           
        }

        /// <summary>
        /// 创建产品套餐
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Add_ProductPackage(AddProductPackage_Dto dto)
        {
            ProductPackage productPackage = new ProductPackage()
            {
                PpId = Config.GenerateOrderId(),
                PpName = dto.name,
                PpDescription = dto.description,
                PpOriginalPrice = (decimal?)dto.originalPrice,
                PpIsBan = 0,
                PpPhoto = dto.coverImage,
                PpPrice = (decimal?)dto.sellingPrice,
                PpRemark = dto.discountDescription,
               
                PpStatus = 1,
                PpCreateTime = DateTime.Now,
                PpEndTime = dto.endDate,
                PpStartTime = DateTime.Now,
                PpUpdateTime = null
            };
            _product_IOC._productPackage_EFCore.Add(productPackage);
            _product_IOC._productPackage_EFCore.SaveChanges();
            List<ProductPackageDetail> productPackageDetails = new List<ProductPackageDetail>();
            dto.selectedSpecs!.ForEach(d =>
            {
                productPackageDetails.Add(new ProductPackageDetail()
                {
                    PpdId = Config.GUID2(),
                    PpdCreateTime = DateTime.Now,
                    PpdPackageId = productPackage.PpId,
                    PpdProductId = d.productId!,
                    PpdProductSpecsId = d.specId,
                   
                    PpdSinglePrice = (decimal?)d.price,
                    PpdRemark = null
                });
            });
            var allProductSpecs = _product_IOC._productSpecs_EFCore.GetAll().ToList();
            productPackageDetails.ForEach(d => {
                d.PpdProductSpecsName = allProductSpecs.Where(c => c.PsId == d.PpdProductSpecsId).Select(c => c.PsName).Single();
            });
            _product_IOC._productPackageDetails_EFCore.AddRange(productPackageDetails);
            var result = await _product_IOC._productPackageDetails_EFCore.SaveChangesAsync();
            return Get_Result(result);
        }

        /// <summary>
        /// 切换产品状态
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> ChangeIsBan_Product(IsBan_Dto dto)
        {
            var data = await _product_IOC._product_EFCore.GetAll(d => d.PId == dto.id).SingleAsync();
            data.PIsBan = dto.isBan ? 0 : 1;
            _product_IOC._product_EFCore.Update(data);
            var result = await _product_IOC._product_EFCore.SaveChangesAsync();
            return Get_Result(result);

        }

        /// <summary>
        /// 切换产品套餐状态
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> ChangeIsBan_ProductPackage(IsBan_Dto dto)
        {
            var data = await _product_IOC._productPackage_EFCore.GetAll(d => d.PpId == dto.id).SingleAsync();
            data.PpIsBan = dto.isBan ? 0 : 1;
            _product_IOC._productPackage_EFCore.Update(data);
            var result = await _product_IOC._productPackage_EFCore.SaveChangesAsync();
            return Get_Result(result);
        }

        /// <summary>
        /// 切换产品文章的发布下架
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> ChangeIsPublish_ProductPackage(IsBan_Dto dto)
        {
            var data =await _product_IOC._productArticle_EFCore.GetAll(d => d.PaId == dto.id).SingleAsync();
            data.PaStatus = dto.isPublish;
            if (dto.isPublish == 1)
            {
                data.PaPublishTime = DateTime.Now;
            }
            else {
                data.PaPublishTime = null;
            }
            _product_IOC._productArticle_EFCore.Update(data);
            var result = await _product_IOC._productArticle_EFCore.SaveChangesAsync();
            return Get_Result(result);
        }

        /// <summary>
        /// 删除产品
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Delete_Product(Delete_Dto dto)
        {

            //先删除规格
            var specs = await _product_IOC._productSpecs_EFCore.GetAll(d => d.PsProductId == dto.id).ToListAsync();
            _product_IOC._productSpecs_EFCore.DeleteRange(specs);
            _product_IOC._productSpecs_EFCore.SaveChanges();
            //删除产品的佣金规则
            var rules = _customer_IOC._commissionRules_EFCore.GetAll(d => d.CrProductId == dto.id).SingleOrDefault();
            _customer_IOC._commissionRules_EFCore.Delete(rules);
            await _customer_IOC._commissionRules_EFCore.SaveChangesAsync();
            var product = await _product_IOC._product_EFCore.GetAll(d => d.PId == dto.id).SingleAsync();
            _product_IOC._product_EFCore.Delete(product);
            var result = await _product_IOC._product_EFCore.SaveChangesAsync();
            return Get_Result(result);
        }

        /// <summary>
        /// 获取产品
        /// </summary>
        /// <param name="fenye_Dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Get_Product(Fenye_Dto dto)
        {
            var data = await _product_IOC._product_EFCore
                .GetAll(out int total, dto.page, dto.limit, false, o => o.PCreateTime, d => d.PName!.Contains(dto.key))
                .Select(d => new Product_Dto()
                {
                    id = d.PId,
                    allphoto = d.PPhoto,
                    attention = d.PProductAttention,
                    cover = d.PCover,
                    description = d.PDescription,
                    effect = d.PProductEffect,
                    isBan = d.PIsBan == 1 ? true : false,
                    isGroup = d.PIsGroup,
                    name = d.PName,
                    type_id = d.PTypeId,
                    remark = d.PRemark,
                    time = d.PCreateTime!.Value.ToString("yyyy-MM-dd HH:mm:ss"),
                }).ToListAsync();

            var type = _sys_IOC._sysDictionary_EFCore.GetAll().ToList();

            var specs = _product_IOC._productSpecs_EFCore.GetAll().ToList();
            data.ForEach(d =>
            {
                d.photo = d.allphoto!.Split(",").ToList();
                d.specs = specs.Where(c => c.PsProductId == d.id).Select(c => new product_specs()
                {
                    id = c.PsId,
                    name = c.PsName,
                    price = c.PsPrice
                }).ToList();
                d.category = type.Where(c => c.DId == d.type_id).Select(c => c.DName).Single();
            });

            return Get_Result(0, "ok", new
            {
                data = data,
                total = total
            });
        }

        /// <summary>
        /// 获取产品文章
        /// </summary>
        /// <param name="fenye_Dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Get_ProductArticle(Fenye_Dto dto)
        {
            var data=await _product_IOC._productArticle_EFCore
                .GetAll(out int total,dto.page,dto.limit,false,o=>o.PaCreateTime,d=>d.PaProductName.Contains(dto.key))
                .Select(d => new ProductArticle_Dto{
                    id=d.PaId,
                productName=d.PaProductName,
                category=d.PaProductType,
                content=d.PaContent,
                status=d.PaStatus==0?"草稿":"已发布",
                views=d.PaLookCount,
                cover=d.PaCover,
                title=d.PaTitle,
                publishDate=d.PaPublishTime.Value.ToString("yyyy-MM-dd HH:mm:ss"),
                })
                .ToListAsync();

            return Get_Result(0, "ok", new { 
            data=data,
            total = total
            });
        }


        /// <summary>
        /// 获取所有产品套餐
        /// </summary>
        /// <param name="fenye_Dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Get_ProductPackage(Fenye_Dto dto)
        {
            List<ProductPackage> productPackage;
            int total;
            // 获取当前时间（可根据需求调整时区或精度）
            DateTime now = DateTime.Now;
            if (dto.isBan == "")
            {
                productPackage = _product_IOC._productPackage_EFCore
                   .GetAll(out  total, dto.page, dto.limit, 
                   false, o => o.PpCreateTime, 
                   d => d.PpName!.Contains(dto.key)
                   && d.PpEndTime>now
                    ).ToList();

            }
            else
            {

                productPackage = _product_IOC._productPackage_EFCore
                   .GetAll(out  total, dto.page, dto.limit,
                   false, o => o.PpCreateTime, 
                   d => d.PpName.Contains(dto.key) && 
                   d.PpIsBan == int.Parse(dto.isBan)
                    && d.PpEndTime > now
                   ).ToList();


            }



            var data = productPackage.Select(d => new ProductPackage_Dto
            {
                id = d.PpId,
                name = d.PpName,
                cover = d.PpPhoto,
                isBan = d.PpIsBan,
                originalPrice = (double?)d.PpOriginalPrice,
                price = (double?)d.PpPrice,
                description = d.PpDescription,
                validPeriod = d.PpEndTime!.Value.ToString("yyyy-MM-dd HH:mm:ss"),

            }).ToList();

            ProductPackageDetails_Dto productPackageDetails = new ProductPackageDetails_Dto();



            List<ProductIncludes_Dto> productIncludes = new List<ProductIncludes_Dto>();
            var all =await _product_IOC._productPackageDetails_EFCore.GetAll().ToListAsync();
            var allProductData =await _product_IOC._product_EFCore.GetAll().ToListAsync();
            data.ForEach(d =>
            {
                d.items = all.Where(c => c.PpdPackageId == d.id).Select(c=>c.PpdProductId).Count();
              
                //找到当前套餐的所有产品
                var allProduct = _product_IOC._productPackageDetails_EFCore.GetAll(e => e.PpdPackageId == d.id).ToList();
                var productPackageDetails = new ProductPackageDetails_Dto
                {
                    description = d.description,
                    includes = new List<ProductIncludes_Dto>()
                };
                allProduct.ForEach((k) =>
                {
                    productPackageDetails.includes
                    .Add(new ProductIncludes_Dto
                    {
                        id = k.PpdProductId,
                        name = allProductData.Where(c => c.PId == k.PpdProductId).Select(c => c.PName).SingleOrDefault(),
                        specs = k.PpdProductSpecsName,
                        price = (double?)k.PpdSinglePrice,

                    });
                   
                });
               
                d.details = productPackageDetails;
            });

            return Get_Result(0, "ok", new { 
            data=data,
            total=total
            });

        }

        /// <summary>
        /// 获取所有的产品套餐可选的产品
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Get_ProductPackageBy_Product()
        {
            //获取所有启用的产品
            var data = await _product_IOC._product_EFCore
               .GetAll(d => d.PIsBan == 0)
               .Select(d => new Product_Dto()
               {
                   id = d.PId,
                   allphoto = d.PPhoto,
                   attention = d.PProductAttention,
                   cover = d.PCover,
                   description = d.PDescription,
                   effect = d.PProductEffect,
                   isBan = d.PIsBan == 1 ? true : false,
                   isGroup = d.PIsGroup,
                   name = d.PName,
                   type_id = d.PTypeId,
                   remark = d.PRemark,
                   time = d.PCreateTime!.Value.ToString("yyyy-MM-dd HH:mm:ss"),
               }).ToListAsync();

            var type = _sys_IOC._sysDictionary_EFCore.GetAll().ToList();

            var specs = _product_IOC._productSpecs_EFCore.GetAll().ToList();
            data.ForEach(d =>
            {
                d.photo = d.allphoto!.Split(",").ToList();
                d.specs = specs.Where(c => c.PsProductId == d.id).Select(c => new product_specs()
                {
                    id = c.PsId,
                    name = c.PsName,
                    price = c.PsPrice
                }).ToList();
                d.category = type.Where(c => c.DId == d.type_id).Select(c => c.DName).Single();
            });

            return Get_Result(0, "ok", data);
        }

        /// <summary>
        /// 停止套餐
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Stop_ProductPackage(string? id)
        {
            var data =await _product_IOC._productPackage_EFCore.GetAll(d => d.PpId == id).SingleOrDefaultAsync();
            data.PpEndTime= DateTime.Now;
            _product_IOC._productPackage_EFCore.Update(data);
            var result = await _product_IOC._productPackage_EFCore.SaveChangesAsync();
            return Get_Result(result);
        }

        /// <summary>
        /// 编辑产品
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Update_Product(UpdateProduct_Dto dto)
        {
            // 1. 更新主产品信息（这部分没问题）
            var product = await _product_IOC._product_EFCore.GetAll(d => d.PId == dto.id).SingleAsync();
            product.PDescription = dto.description;
            product.PName = dto.name;
            product.PPhoto = dto.allPhoto;
            product.PCover = dto.cover;
            product.PProductAttention = dto.attention;
            product.PProductEffect = dto.effect;
            product.PRemark = dto.remark;
            product.PTypeId = dto.category;
            product.PUpdateTime = DateTime.Now;
            _product_IOC._product_EFCore.Update(product);
            await _product_IOC._product_EFCore.SaveChangesAsync();

            // 2. 修改规格：用 foreach 替代 ForEach，确保每个异步操作被等待
            foreach (var d in dto.specs)  // 关键：改用普通 foreach
            {
                // 等待查询完成，确保获取到 specs 对象
                var specs = await _product_IOC._productSpecs_EFCore.GetAll(c => c.PsId == d.id).SingleOrDefaultAsync();
                // 注意：需判断 specs 是否为 null，避免空引用异常

                specs.PsName = d.name;
                specs.PsPrice = d.price;
                _product_IOC._productSpecs_EFCore.Update(specs);
            }

            // 3. 等待所有规格修改完成后，再保存
            var result = await _product_IOC._productSpecs_EFCore.SaveChangesAsync();

            return Get_Result(result);
        }

        /// <summary>
        /// 编辑产品套餐
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Api_Result_Dto> Update_ProductPackage(UpdateProfuctPackage_Dto dto)
        {
            var data =await _product_IOC._productPackage_EFCore.GetAll(d => d.PpId == dto.id).SingleAsync();
            data.PpName = dto.name;
            data.PpEndTime = dto.validPeriod;
            data.PpPrice = (decimal?)dto.price;
            data.PpPhoto = dto.cover;
            data.PpDescription = dto.description;
            _product_IOC._productPackage_EFCore.Update(data);
            var result = await _product_IOC._productPackage_EFCore.SaveChangesAsync();
            return Get_Result(result);
        }
    }
}
